﻿using HDJ.Framework.Core;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.Graphs;
using UnityEngine;

public class TestW: EditorWindow
{
    [MenuItem("Tools/状态机")]
    public static void Do()
    {
        StateMachineData<StateDataBase, StateTransitionDataBase> machineData = new StateMachineData<StateDataBase, StateTransitionDataBase>();
        SM_EditorController<StateDataBase, StateTransitionDataBase>.Init(machineData,GetWindow<TestW>());
    }

    private void OnGUI()
    {
        if (SM_EditorController<StateDataBase, StateTransitionDataBase>.Instance == null)
            return;
        SM_EditorController<StateDataBase, StateTransitionDataBase>.Instance.OnGUI();
    }
    private void OnDestroy()
    {
        if (SM_EditorController<StateDataBase, StateTransitionDataBase>.Instance == null)
            return;
        SM_EditorController<StateDataBase, StateTransitionDataBase>.Instance.OnDestroy();
    }
}
/// <summary>
/// 状态机编辑器管理界面
/// </summary>
/// <typeparam name="S">继承于StateDataBase的状态数据类</typeparam>
/// <typeparam name="T">继承于StateTransitionDataBase的状态间过度数据类</typeparam>
public class SM_EditorController<S, T>  where S : StateDataBase, new() where T : StateTransitionDataBase, new()
{
    /// <summary>
    /// 自定义绘制左半边界面的回掉
    /// </summary>
    public  CallBack OnDrawLeftPartGUI;
    /// <summary>
    /// 自定义绘制中间顶部的界面
    /// </summary>
    public  CallBack OnDrawTopToolBarGUI;

    /// <summary>
    /// 添加状态时回掉
    /// </summary>
    public  CallBack<StateGUIData<S>> OnStateAdd;
    public  CallBack<StateGUIData<S>> OnStateDelete;
    /// <summary>
    /// 添加过渡线时回掉
    /// </summary>
    public  CallBack<TransitionGUIData<T>,T> OnTransitionAdd;
    public  CallBack<TransitionGUIData<T>,T> OnTransitionDelete;

    /// <summary>
    /// 状态机的所有状态以及过度数据
    /// </summary>
    public StateMachineData<S, T> machineData;
    /// <summary>
    /// 显示状态机的Editor UI控件数据
    /// </summary>
    public StateMachineEditorData<S, T> machineEditorData;

    public static SM_EditorController<S, T> Instance;
    public  EditorWindow win;

    /// <summary>
    /// 初始化
    /// </summary>
    /// <param name="machineData">传入状态机数据</param>
    /// <param name="win">编辑器window类</param>
    /// <returns></returns>
    public static SM_EditorController<S, T> Init(StateMachineData<S, T> machineData, EditorWindow win)
    {

        Instance = new SM_EditorController<S, T>();
        Instance.machineData = machineData;

        Instance.win = win;
        win.Show();
        win.Focus();
        win.autoRepaintOnSceneChange = true;
        win.wantsMouseEnterLeaveWindow = true;
        win.wantsMouseMove = true;

        Instance.inputController = new SM_InputEventController<S, T>(Instance);
        Instance.machineEditorData = new StateMachineEditorData<S, T>(machineData,Instance);

        return Instance;
        
    }
    private SM_InputEventController<S, T> inputController;
    private Rect ndoeControlRange;
    public void OnGUI()
    {
        ndoeControlRange = new Rect(leftToolAreaRect.xMax, topRightToolBarRect.yMax, win.position.width - leftToolAreaRect.width - rightToolAreaRect.width, win.position.height - topRightToolBarRect.height);

        SM_DrawBGGUIUtils.BeginGUI(ndoeControlRange, machineEditorData.GetStateMachineGUIMaxRange());
        win.BeginWindows();
        DrawTransitionGUIUtils<S, T>.DrawTempArrowTransition();
        machineEditorData.DrawGUI();

        win.EndWindows();
        SM_DrawBGGUIUtils.EndGUI();

        DrawLeftToolAreaGUI();
        DrawToolBarGUI();
        DrawRightToolAreaGUI();
        inputController.PlayerControlUse();
    }

    public Rect leftToolAreaRect =new Rect(0,0,Screen.width/4,0);
    /// <summary>
    /// 绘制左侧区域
    /// </summary>
    void DrawLeftToolAreaGUI()
    {
        if (leftToolAreaRect.xMax < 10)
            leftToolAreaRect.xMax = 10;
        Rect maxArea = new Rect(0, 0, win.position.width -rightToolAreaRect.width-10, win.position.height);
        leftToolAreaRect= EditorDrawGUIUtility.DrawCanDragArea(leftToolAreaRect, maxArea, () =>
        {
            if (OnDrawLeftPartGUI != null)
                OnDrawLeftPartGUI();
        }, EditorCanDragAreaSide.Right, Styles.graphBackground.name);

    }

    public Rect topRightToolBarRect;
    //绘制中间上方区域
    void DrawToolBarGUI()
    {
        topRightToolBarRect = new Rect(leftToolAreaRect.xMax, 0, Screen.width - leftToolAreaRect.width, 25f);

        GUIStyle style = "flow overlay header lower left";
        GUILayout.BeginArea(topRightToolBarRect, style);
        GUILayout.BeginHorizontal(style);

        if (OnDrawTopToolBarGUI != null)
            OnDrawTopToolBarGUI();

        GUILayout.EndHorizontal();
        GUILayout.EndArea();
    }

    public Rect rightToolAreaRect = new Rect(Screen.width * 3 / 4, 0, Screen.width / 4, 0);
    //绘制右边区域
    void DrawRightToolAreaGUI()
    {
        Rect maxArea = new Rect(leftToolAreaRect.xMax + 10, 0, win.position.width - leftToolAreaRect.width - 10, win.position.height);
        rightToolAreaRect= EditorDrawGUIUtility.DrawCanDragArea(rightToolAreaRect, maxArea, () =>
          {
              if (SelectObjectController<S, T>.SelectObject != null)
              {
                  if (SelectObjectController<S, T>.SelectObject is StateGUIData<S>)
                      StateGUIInspector<S, T>.OnHeaderGUI((StateGUIData<S>)SelectObjectController<S, T>.SelectObject);
                  else if (SelectObjectController<S, T>.SelectObject is TransitionGUIData<T>)
                  {
                      TransitionGUIInspector<S, T>.OnHeaderGUI((TransitionGUIData<T>)SelectObjectController<S, T>.SelectObject);
                  }
              }
          }, EditorCanDragAreaSide.Left, Styles.graphBackground.name);

    }
    public void ClearAllData()
    {
        machineData.Clear();
    }
  public  void OnDestroy()
    {
        machineData.Clear();
        OnDrawLeftPartGUI = null;
        OnDrawTopToolBarGUI = null;
        OnStateAdd = null;
        OnStateDelete = null;
        OnTransitionAdd = null;
        OnTransitionDelete = null;
       
        SelectObjectController<S, T>.SelectObject = null;
    }
}
